/**
 * Created with JetBrains WebStorm.
 * User: Administrator
 * Date: 14-6-11
 * Time: 下午4:44
 * To change this template use File | Settings | File Templates.
 */
define(function(require,exports,module){
    var VERSION = '1.0',
        jQuery = $ = require("jquery-1.8.2.min");

    var firstClick = false,
        letters = ['_', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '-'];

    var defaults = {
        initLetter:'',
        includeAll:true,
        includeOther:false,
        includeNums:true,
        flagDisabled:true,
        removeDisabled:false,
        noMatchText:"没有找到相关记录",
        showCounts:true,
        cookieName:null,
        onClick:null,
        prefixes:[],
        filterSelector:''
    };

    var $wrapper,$letters,$letterCount,
        counts = {},allCounts = 0,
        prevLetter = '',isAll = true;

    function listnav(elem,options){
        this.$elem = $(elem);
        this.options = $.extend({},defaults,options);
        this.init();
    }

    listnav.prototype = {
        init:function(){
            var options = this.options;
            this.initDom();
            var navhtml = this.createLettersHtml();
            $wrapper.append(navhtml);
            $letters = $(".ln-letters",$wrapper).slice(0,1);
            if(options.showCounts){
                $letterCount = $('.ln-letter-count',$wrapper).slice(0,1)
            }
            this.addClasses();
            this.addNoMatchLi();
            this.bindHandlers();

            if(options.flagDisabled){
                this.addDisabledClass();
            }
            if(!options.includeAll){
                $(".all",$letters).remove();
            }
            if(!options.includeNums){
                $("._",$letters).remove();
            }
            if(options.removeDisabled){
                $(".ln-disabled",$letters).remove();
            }
            $(":last",$letters).addClass("ln-last");
            if($.cookie && (options.cookieName !== null)){
                var cookieLetter = $.cookie(options.cookieName);
                if(cookieLetter !== null){
                    options.initLetter = cookieLetter;
                }
            }

            if(options.initLetter !== ""){
                firstClick = true;
                $("." + options.initLetter.toLowerCase(),$letters).slice(0,1).trigger("click");
            }else{
                if(options.includeAll){
                    $(".all",$letters).addClass("ln-selected");
                }else{
                    for(var i = ((options.includeNums) ? 0 : 1);i<letters.length;i++){
                        if(counts[letters[i]] > 0){
                            firstClick = true;
                            $("." + letters[i],$letters).slice(0,1).trigger("click");
                            break;
                        }
                    }
                }
            }
        },
        initDom:function(){
            var $elem = this.$elem;
            var id = $elem.attr("id");
            if(!$("#" + id + "-nav").length){
                $('<div id="' + id + '-nav" class="listNav"/>').insertBefore($elem)
            }
            $wrapper = $("#" + id + "-nav");

        },
        setLetterCountTop:function(){
            var letterCountHeight = $letterCount.outerHeight();
            $letterCount.css({
                top:$("a:first",$wrapper).slice(0,1).position().top - letterCountHeight
            })
        },
        addClasses:function(){
            var options = this.options,
                $elem = this.$elem,
                that = this;
            var str,$this,
                firstChar = '',
                hasPrefixes = (options.prefixes.length >0),
                hasFilterSelector = (options.filterSelector.length > 0);

            $elem.children().each(function(){
                $this = $(this);
                if(!hasFilterSelector){
                    str = $.trim($this.text()).toLowerCase();
                }else{
                    str = $.trim($this.find(options.filterSelector).text()).toLowerCase();
                }

                if(str !== ""){
                    if(hasPrefixes){
                        var prefixes = $.map(options.prefixes,function(value){
                            return value.indexOf(" ") <= 0 ? value + "" : value;
                        });

                        var matches = $.grep(prefixes,function(value){
                            return str.indexOf(value) === 0;
                        });

                        if(matches.length > 0 ){
                            var afterMatch = str.toLowerCase().split(matches[0])[1];
                            if(afterMatch != null){
                                firstChar = $.trim(afterMatch).charAt(0);
                            }else{
                                firstChar = str.charAt(0);
                            }
                            that.addLetterClass(firstChar,$this,true);
                        }
                    }
                    firstChar = str.charAt(0);
                    that.addLetterClass(firstChar,$this);
                }
            })
        },
        addLetterClass:function(firstChar,$el,isPrefix){
            if(/\W/.test(firstChar)){
                firstChar = '-';
            }

            if(!isNaN(firstChar)){
                firstChar = "_";
            }

            $el.addClass("ln-"+firstChar);
            if(counts[firstChar] === undefined){
                counts[firstChar] = 0;
            }

            counts[firstChar]++;
            if(!isPrefix){
                allCounts++;
            }
        },
        addDisabledClass:function(){
            for(var i = 0;i < letters.length;i++){
                if(counts[letters[i]] === undefined){
                    $("." + letters[i],$letters).addClass("ln-disabeld");
                }
            }
        },
        addNoMatchLi:function(){
            var $elem = this.$elem,
                options = this.options;
            $elem.append('<li class="ln-no-match listNavHide">' + options.noMatchText +'</li> ');
        },
        getLetterCount:function(el){
            if($(el).hasClass("all")){
                return allCounts;
            }else{
                var count = counts[$(el).attr("class").split(" ")[0]];
                return (count !== undefined) ? count : 0;
            }
        },
        bindHandlers:function(){
            var that = this;
            var options = this.options,
                $elem = this.$elem;
            if(options.showCounts){
                $wrapper.mouseover(function(){
                    that.setLetterCountTop();
                });

                $(".ln-letters a",$wrapper).mouseover(function(){
                    var left = $(this).position().left,
                        width = ($(this).outerWidth()) + "px",
                        count = that.getLetterCount(this);
                    $letterCount.css({
                        left:left,
                        width:width
                    }).text(count).addClass("letterCountShow").removeClass("listNavHide");
                }).mouseout(function(){
                        $letterCount.addClass("listNavHide").removeClass("letterCountShow");
                })
            }

            $("a",$letters).bind("click",function(e){
                e.preventDefault();

                var $this = $(this),
                    letter = $this.attr("class").split(" ")[0],
                    noMatches = $elem.children(".ln-no-match");

                if(prevLetter !== letter){
                    $("a.ln-selected",$letters).removeClass("ln-selected");
                    if(letter === "all"){
                        $elem.children().addClass("listNavShow").removeClass("listNavHide") ;
                        noMatches.addClass("listNavHide").removeClass("listNavShow");
                        isAll = true;
                    }else{
                        if(isAll){
                            $elem.children().addClass("listNavHide").removeClass("listNavShow");
                            isAll = false;
                        }else if(prevLetter!==''){
                            $elem.children(".ln-"+prevLetter).addClass("listNavHide").removeClass("listNavShow");
                        }

                        var count = that.getLetterCount(this);

                        if(count > 0){
                            $elem.children(".ln-"+letter).addClass("listNavShow").removeClass("listNavHide");
                            noMatches.addClass("listNavHide").removeClass("listNavShow");
                        }else{
                            noMatches.addClass("listNavShow").removeClass("listNavHide");
                        }
                    }
                }

                prevLetter = letter;

                if($.cookie && (options.cookieName!==null)){
                    $.cookie(options.cookieName,letter,{
                        expires:999
                    });
                }

                $this.addClass("ln-selected");
                $this.blur();

                if(!firstClick && (options.onClick!==null)){
                    options.onClick(letter);
                }else{
                    firstClick = false;
                }
            });
        },
        createLettersHtml:function(){
            var options = this.options;
            var html = [];
            for(var i = 1;i < letters.length;i++){
                if(html.length === 0){
                    html.push('<a class="all" href="#">All</a><a class="_" href="#">0-9</a>');
                }
                html.push('<a class="' + letters[i] + '" href="#">' + ((letters[i] === '-') ? '...' : letters[i].toUpperCase()) + '</a>');
            }
            return '<div class="ln-letters">' + html.join('') + '</div>' + ((options.showCounts) ? '<div class="ln-letter-count listNavHide">0</div>' : '');
        }
    };

    return listnav;
})